/*
Eteria IRC Client, an RFC 1459 compliant client program written in Java.
Copyright (C) 2000-2001  Javier Kohen <jkohen at tough.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package ar.com.jkohen.awt;

import java.awt.Color;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import ar.com.jkohen.awt.SimpleNickInfo;
import ar.com.jkohen.awt.ExtendedNickInfo;

public class NickInfo
{
	private static Hashtable nickInfos = new Hashtable();
	private static Hashtable TLD = new Hashtable();
	
    public static final int SEX_UNKNOWN = 0;
    public static final int SEX_MALE = 1;
    public static final int SEX_FEMALE = 2;

    public static final Color COLOR_UNKNOWN = new Color(0x55, 0x55, 0x55);
    public static final Color COLOR_MALE = new Color(0x00, 0x00, 0xAA);
    public static final Color COLOR_FEMALE = new Color(0xAA, 0x00, 0xAA);
    
    public static final int ASL_COOLSMILE = 0;
    public static final int ASL_EPIKNET = 1;
    public static final int ASL_LANGOCHAT = 2;
    
    public static int type = ASL_COOLSMILE;
	
    public static void add(String nick, String info, String user, String inetAddr)
    {
		if (nick == null || nick.equals(""))
			return;

		// Strip useless chars.
		String s = info;
		if (s.length() > 2)
			info = s.substring(2);
		
    	Vector v = getASL(info);
	   	if (v == null)
    	{
			nickInfos.put(nick, new SimpleNickInfo(info, user, inetAddr));
		}
		else
		{
			int age = ((Integer)v.firstElement()).intValue();
			int sex = ((Integer)v.elementAt(1)).intValue();
			String loc = (String)v.lastElement();
			nickInfos.put(nick, new ExtendedNickInfo(age, sex, loc, user, inetAddr));
		}
    }
    
    public static void setParseASLType(int t)
    {
    	type = t;
    }
	
	public static Vector getASL(String info)
	{
		Vector v;
		switch (type)
    	{
    	case ASL_EPIKNET:
    	    v = parseEpiknet(info);
    	    break;
    	case ASL_LANGOCHAT:
    	    v = parseLangochat(info);
    	    break;
    	case ASL_COOLSMILE:
    	default:
    	    v = parseCoolSmile(info);
    	}
		return(v);
	}
	
	public static String fromASL(String a, int s, String l)
	{
		String ASL = "?";
		switch (type)
    	{
    	case ASL_EPIKNET:
    	    ASL = "[A:" + a + "|S:";
			if (s == SEX_MALE) ASL = ASL + "H";
			if (s == SEX_FEMALE) ASL = ASL + "F";
			ASL = ASL + "|R:|V:" + l + "]";
    	    break;
    	case ASL_LANGOCHAT:
    	    ASL = a;
			if (s == SEX_MALE) ASL = ASL + "M";
			if (s == SEX_FEMALE) ASL = ASL + "F";
			if (s == SEX_UNKNOWN) ASL = ASL + "U";
			ASL = ASL + "002" + l;
    	    break;
    	case ASL_COOLSMILE:
    	default:
    	    ASL = a + " ";
			if (s == SEX_MALE) ASL = ASL + "M";
			if (s == SEX_FEMALE) ASL = ASL + "F";
			if (s == SEX_UNKNOWN) ASL = ASL + "?";
			ASL = ASL + " " + l;
    	    break;
    	}
		return(ASL);
	}
    
	private static Vector parseCoolSmile(String info)
    {
    	try
    	{
        	int start = 0;
   			int age = 0;
   			char c1 = info.charAt(start);
   			char c2 = info.charAt(start + 1);
   			if (Character.isDigit(c1) && Character.isDigit(c2))
			{
   				age = Integer.parseInt(String.valueOf(c1) + String.valueOf(c2));
				start += 3;
			}
   			else
			{
				if (Character.isDigit(c1) && c2 == ' ')
				{
   					age = Integer.parseInt(String.valueOf(c1));
					start += 2;
				}
				else
				{
					return(null);
				}
			}
   			
   			char sex = '?';
			if (start < info.length())
	    		sex = info.charAt(start);

   		    int sex_val;
   		    switch (Character.toUpperCase(sex))
   		    {
   		    case 'M':
   				sex_val = SEX_MALE;
   				break;
   		    case 'F':
   				sex_val = SEX_FEMALE;
   				break;
   		    default:
   				sex_val = SEX_UNKNOWN;
   				break;
   	    	}
			start += 2;
			
   			String loc = "";
			if (start < info.length())
	    		loc = info.substring(start);
			
			Vector v = new Vector(3, 0);
			v.addElement(new Integer(age));
			v.addElement(new Integer(sex_val));
			v.addElement(loc);
   		    return(v);
    	}
		catch (StringIndexOutOfBoundsException e) {}
		catch (NumberFormatException e) {}
		
		return(null);
    }
	
	private static Vector parseEpiknet(String info)
    {
        int start1 = -1, start2 = -1, start3 = -1;
    	try
    	{
        	start1 = info.toUpperCase().indexOf("A:");
    		start2 = info.toUpperCase().indexOf("S:");
    		start3 = info.toUpperCase().indexOf("V:");
    		if (start1 >= 0 || start2 >= 0 || start3 >= 0)
    		{
    			int age = 0;
    			start1 += 2;
    			char c1 = info.charAt(start1);
    			char c2 = info.charAt(start1 + 1);
    			if (Character.isDigit(c1) && Character.isDigit(c2))
    				age = Integer.parseInt(String.valueOf(c1) + String.valueOf(c2));
    			else if (Character.isDigit(c1))
    				age = Integer.parseInt(String.valueOf(c1));
    			
    			char sex = '?';
    	    	start2 += 2;
    			if (start2 > 1)
    	    		sex = info.charAt(start2);

    		    int sex_val;
    		    switch (Character.toUpperCase(sex))
    		    {
    		    case 'H':
    				sex_val = SEX_MALE;
    				break;
    		    case 'F':
    				sex_val = SEX_FEMALE;
    				break;
    		    default:
    				sex_val = SEX_UNKNOWN;
    				break;
    	    	}

    			String loc = "";
    	    	start3 += 2;
				int end = info.indexOf("]", start3);
    			if (end > start3)
    	    		loc = info.substring(start3, end);
    				
    		    Vector v = new Vector(3, 0);
				v.addElement(new Integer(age));
				v.addElement(new Integer(sex_val));
				v.addElement(loc);
   			    return(v);
    		}
    	}
		catch (StringIndexOutOfBoundsException e) {}
		catch (NumberFormatException e) {}
    	
		return(null);
    }
    
	private static Vector parseLangochat(String info)
    {
		try
    	{
			int start = 0;
   			int age = 0;
   			char c1 = info.charAt(start);
   			char c2 = info.charAt(start + 1);

   			if (Character.isDigit(c1) && Character.isDigit(c2))
   			{
   				age = Integer.parseInt(String.valueOf(c1) + String.valueOf(c2));
   				start += 2;
   			}
   			else if (Character.isDigit(c1))
   			{
   				age = Integer.parseInt(String.valueOf(c1));
   				start++;
   			}
    			
   			char sex = '?';
       		sex = info.charAt(start);

   		    int sex_val;
   		    switch (Character.toUpperCase(sex))
   		    {
   		    case 'M':
   				sex_val = SEX_MALE;
   				break;
   		    case 'F':
   				sex_val = SEX_FEMALE;
   				break;
   		    case 'U':
   				sex_val = SEX_UNKNOWN;
   				break;
   			default:
   				return(null);
   	    	}

   			String loc = "";
   	    	start += 4;
   	    	loc = info.substring(start);

   		    Vector v = new Vector(3, 0);
			v.addElement(new Integer(age));
			v.addElement(new Integer(sex_val));
			v.addElement(loc);
   		    return(v);
		}
		catch (StringIndexOutOfBoundsException e) {}
		catch (NumberFormatException e) {}
		
		return(null);
    }
    
    public static boolean remove(String nick)
	{
		if (nickInfos.remove(nick) != null)
			return(true);
		else
			return(false);
    }
    
  	public static boolean hasInfos(String nick)
    {
		if(getLocation(nick) != null)
			return(true);
		else
			return(false);
    }
	
    public static Color nickToColor(String nick)
    {
		return (sexToColor(getSex(nick)));
    }
	
    public static Color sexToColor(int sex)
    {
		switch (sex)
		{
		// FIXME: there could be a law prohibiting this.
		case SEX_MALE:
		    return COLOR_MALE;
		case SEX_FEMALE:
		    return COLOR_FEMALE;
		default:
		    return COLOR_UNKNOWN;
		}
    }
   
    public static char nickToChar(String nick)
    {
		switch (getSex(nick))
		{
		// FIXME: there could be a law prohibiting this.
		case SEX_MALE:
		    return 'M';
		case SEX_FEMALE:
		    return 'F';
		default:
		    return '?';
		}
    }
    
    public static boolean changeNick(String oldNick, String newNick)
	{
		Object o = nickInfos.get(oldNick);
		if (o != null)
		{
			nickInfos.remove(oldNick);
			nickInfos.put(newNick, o);
			return(true);
		}
		return(false);
    }
    
    public static int getAge(String nick)
    {
		if (nickInfos != null)
		{
			Object o = nickInfos.get(nick);
		
			if (o instanceof ExtendedNickInfo)
			{
				ExtendedNickInfo ni = (ExtendedNickInfo)o;
				return(ni.age);
			}
		}
		return(-1);
    }
    
    public static int getSex(String nick)
    {
		if (nick != null)
		{
			Object o = nickInfos.get(nick);
		
			if (o instanceof ExtendedNickInfo)
			{
				ExtendedNickInfo ni = (ExtendedNickInfo)o;
				return(ni.sex);
			}
		}
		return(0);
	}
    
    public static String getLocation(String nick)
    {
		if (nick != null)
		{
			Object o = nickInfos.get(nick);
		
			if (o instanceof ExtendedNickInfo)
			{
				ExtendedNickInfo ni = (ExtendedNickInfo)o;
				return(ni.location);
			}
			else if (o instanceof SimpleNickInfo)
			{
				SimpleNickInfo ni = (SimpleNickInfo)o;
				return(ni.description);
			}
		}
		return(null);
	}
	
  	public static String getDescription(String nick)
    {
		if (nick != null)
		{
			Object o = nickInfos.get(nick);
		
			if (o instanceof SimpleNickInfo)
			{
				SimpleNickInfo ni = (SimpleNickInfo)o;
				return(ni.description);
			}
		}
		return(null);
    }
    
  	public static String getUser(String nick)
    {
		if (nick != null)
		{
			Object o = nickInfos.get(nick);
		
			if (o instanceof SimpleNickInfo)
			{
				SimpleNickInfo ni = (SimpleNickInfo)o;
				return(ni.user);
			}
			else if (o instanceof ExtendedNickInfo)
			{
				ExtendedNickInfo ni = (ExtendedNickInfo)o;
				return(ni.user);
			}
		}
		return(null);
    }
	
  	public static String getInetAddr(String nick)
    {
		if (nick != null)
		{
			Object o = nickInfos.get(nick);
		
			if (o instanceof SimpleNickInfo)
			{
				SimpleNickInfo ni = (SimpleNickInfo)o;
				return(ni.inetAddr);
			}
			else if (o instanceof ExtendedNickInfo)
			{
				ExtendedNickInfo ni = (ExtendedNickInfo)o;
				return(ni.inetAddr);
			}
		}
		return(null);
    }

	public static String getCountry(String nick)
    {
		String inetAddr = getInetAddr(nick);
 	   	String country = "";
 	   	if (inetAddr != null)
 	   	{
			for (Enumeration e = TLD.keys() ; e.hasMoreElements() ;)
			{
				String tld = (String)e.nextElement();
				if (inetAddr.endsWith(tld))
					country = (String)TLD.get(tld);
			}
    	}
		return(country);
    }
	
	public static void addTLD(String tld, String desc)
    {
    	TLD.put(tld, desc);
    }
	
    public static void clear()
    {
    	nickInfos.clear();
    }
    
    public static Vector getList()
    {
    	Vector v = new Vector();
		for (Enumeration e = nickInfos.keys(); e.hasMoreElements(); )
			v.addElement(e.nextElement());
		return(v);
    }
}
